#ifndef PCRSTATE_H
#define PCRSTATE_H

#define FAILURE_VALUE "nan"

#include <QString>
#include <QList>
#include <QVector>
#include <QMap>
#include <QSet>
#include <QPointF>
#include <QWidget>
#include <QSqlDatabase>
#include <QMessageBox>
#include "dbHelper.h"
#include "qpcrModel.h"
#include "debugLog.h"


#include <QTableWidget>

class PCRStateCalculator;


// 曲线名定义：通道名_孔位名，例FAM_A5
class ChannelName : public QString{
public:
    ChannelName(QString a);
    ChannelName(const char *unicode);
    bool operator > (ChannelName&);
    bool operator < (ChannelName&);
};

class PosiName : public QString{
public:
    PosiName(QString a);
    PosiName(const char *unicode);
    bool operator > (PosiName&);
    bool operator < (PosiName&);
};

class CurveName : public QString{
public:
    CurveName(QString a);
    CurveName(QString a, QString b);
    CurveName(const char *unicode);

    PosiName posi() const;
    ChannelName channel() const;

    bool operator > (CurveName&);
    bool operator < (CurveName&);
};



// 全局状态数据
class PCRState : public QWidget
{
    Q_OBJECT

public:
    PCRState();
    ~PCRState();

    void init();
    void calModel();
    void calCt();
    void calStandardCurve();

public:
    void emitPageChanged();
    void emitFilterChanged();
    void emitThrChanged();
    void emitBoldResultChanged();
    void emitFilterResultChanged();
    void emitModelChanged();
    void emitFilterStart();
    void emitStandardChanged();
    void emitGuideNumChanged();
    void emitGuidePageChanged();

signals:
    void sigPageChanged();
    void sigFilterChanged();
    void sigThrChanged();
    void sigBoldResultChanged();
    void sigFilterResultChanged();
    void sigModelChanged();
    void sigFilterStart();
    void sigStandardChanged();
    void sigGuideNumChanged();
    void sigGuidePageChanged();


public:

    // 页面状态控制  信号: sigPageChanged()
    enum PageType{
        RAW,
        RN,
        DELTA_RN,
        LOG_RN,
        LOG_DELTA_RN,
        NORM_RN,
        STANDARD,
        GUIDE_DATA,
        GUIDE_PLAN
    };


    PageType        currentPage;
    int             guidePage;
    bool            showThr;


    // 筛选条件 信号: sigFilterChanged()
    QVector<PosiName>           posiList;
    QVector<QString>            nameList;
    QVector<QString>            typeList;
    QVector<ChannelName>        channelList;

    QVector<PosiName>           posiList_filter;
    QVector<QString>            nameList_filter;
    QVector<QString>            typeList_filter;
    QVector<ChannelName>        channelList_filter;



    // 筛选结果 信号: sigFilterResultChanged()
    QStringList                       filterResult;
    // 加粗曲线 信号: sigBoldResultChanged()
    QStringList                       boldResult;


    // 分析配置
    int         modelFunc;
    int         modelCt;
    int         modelFilter;
    QMap<QString, int>    modelRange_start;       // 一个并没有什么用的参数
    QMap<QString, int>    modelRange_end;
    bool        modelAutoThr;

    // 数据    // [数据缓存]
    double                                  cycleNum;
    QMap<CurveName, QVector<QPointF>>       rawData;       // 从数据库读取的原始数据 QSring=通道号+孔位号
    QMap<CurveName, QVector<QPointF>>       rawData_filter;     // QMap<C_P, 数据列表>
    QMap<CurveName, QPCRModel::Model*>      modelList;         // 每个数据装配一个Model
    // [数据信息]
    QMap<QString, QVector<QString>>         sampleInfo;
    QMap<PosiName, QVector<QString>>        sampleInfo_posi; // QMap<Posi, 孔位信息> QString 0:孔位 1:样本名称 2:样本类型 3:浓度

    // 阈值参数
    QMap<ChannelName, double>               thrList;         // QMap<Channel, 阈值>
    QMap<ChannelName, double>               thrList_log;
    QMap<ChannelName, double>               thrList_diff;   // 标准化阈值线 (无法和thrList转化)

    QMap<ChannelName, double>               thrList_Rn;     // Rn哪来的阈值线
    QMap<ChannelName, double>               thrList_logRn;

    QMap<CurveName, double>                 Ct;             // 根据当前阈值线获取的Ct
    QMap<ChannelName, double>               avgCt;


    QString                                 modelIR;        // 内标
    QMap<PosiName, double>                  rangeIR;        // 内标孔位的曲线范围，用于标准化



    QMap<ChannelName, double>               E;

    // 标准曲线参数
    QMap<ChannelName, QVector<double>>      standardLine;   // 标准曲线计算结果QMap<通道名, 结果> 0-k 1-b
    QMap<CurveName, QPointF>                standardPoint;  // 标准曲线在图上的点
    QMap<CurveName, double>                 concList;       // QMap<C_P, 浓度>
    QMap<ChannelName, double>               avgConcList;    // QMap<Channel, 浓度>

    // 指导意见参数
    QMap<PosiName, double>                  ICS;
    QMap<PosiName, double>                  DI;

    int                     guideSum     = 0;
    int                     guideCSTR    = 0;
    int                     guideYSTR    = 0;
    int                     guideMiniSTR = 0;
    int                     guideDilute  = 0;

    QTableWidget*                           _table;         // 数据不要乱放的……


    // 指导建议数量
    int     guide_count;
    int     guide_miniSTR;
    int     guide_YSTR;
    int     guide_dilute;

    bool    canAnalysis = false;

    QString     experimentName;
    QString     experimentRunTime;
    QString     experimentFinishTime;


};

class PCRStateCalculator
{
public:
    PCRStateCalculator(PCRState* state);

private:

    PCRState*   pState;

};


#endif // PCRSTATE_H
